﻿using System.Collections;
using System.Collections.Generic;
using NHibernate;

namespace ProcelNasEscolas.Data
{
    public class HibernateDAO<T> : IDAO<T>
    {
        #region IDAO<T> Members

        public virtual IList<T> QueryHQL(string query)
        {
            ISession session = SessionManager.GetSession();
            IList<T> List = new List<T>();
            IQuery q = session.CreateQuery(query);
            List = q.List<T>();
            return List;
        }

        public virtual T QueryHQLElement(string query)
        {
                ISession session = SessionManager.GetSession();
                IList<T> List = new List<T>();
                IQuery q = session.CreateQuery(query);
                List = q.List<T>();
                return List[0];  
        }

        public virtual T FindById(object id)
        {
            return SessionManager.GetSession().Get<T>(id);
        }

        public virtual IList<T> FindAll()
        {
            return SessionManager.GetSession().CreateCriteria(typeof(T)).List<T>();
        }

        public virtual void Save(T entity)
        {
            SessionManager.GetSession().SaveOrUpdate(entity);
            SessionManager.GetSession().Flush();
        }

        public virtual void Update(T entity)
        {
            try
            {
                SessionManager.GetSession().Update(entity);
                SessionManager.GetSession().Flush();
            }
            catch (StaleObjectStateException)
            {
                throw new ConcurrentUpdateException(entity.GetType().Name);
            }
        }

        public virtual void SaveOrUpdate(T entity)
        {
            try
            {
                SessionManager.GetSession().SaveOrUpdate(entity);
                SessionManager.GetSession().Flush();
            }
            catch (StaleObjectStateException)
            {
                throw new ConcurrentUpdateException(entity.GetType().Name);
            }
        }

        public virtual void Delete(T entity)
        {
            SessionManager.GetSession().Delete(entity);
            SessionManager.GetSession().Flush();
        }

        public virtual T Refresh(T entity)
        {
            SessionManager.GetSession().Refresh(entity);
            return entity;
        }

        public virtual T Load(object id)
        {
            return SessionManager.GetSession().Load<T>(id);
        }

        public virtual void FlushAll()
        {
            SessionManager.GetSession().Flush();
        }

        public virtual void Reconnect(T entity)
        {
            SessionManager.GetSession().Lock(entity, LockMode.None);
        }

        public virtual void Disconnect(T entity)
        {
            SessionManager.GetSession().Evict(entity);
        }

        #endregion
    }
}
